"use strict";

require("core-js/modules/es.object.keys");

require("core-js/modules/es.object.to-string");

require("core-js/modules/es.promise");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.loop = exports.conditional = exports.parse = void 0;

var parse = function parse(stream, schema) {
  var result = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  var parent = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : result;
  var events = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};

  var parseMain = function parseMain() {
    if (events.terminated) {
      return result;
    }

    if (Array.isArray(schema)) {
      var promiseLoop = Promise.resolve();

      var _loop = function _loop(i) {
        var partSchema = schema[i];
        promiseLoop = promiseLoop.then(function () {
          return parse(stream, partSchema, result, parent, events);
        });
      };

      for (var i = 0; i < schema.length; i++) {
        _loop(i);
      }

      return promiseLoop;
    }

    if (typeof schema === 'function') {
      // read
      return schema(stream, result, parent, parse, events);
    }

    var key = Object.keys(schema)[0];

    if (Array.isArray(schema[key])) {
      parent[key] = {};
      return parse(stream, schema[key], result, parent[key], events);
    } else {
      //read
      return Promise.resolve(schema[key](stream, result, parent, parse, events)).then(function (v) {
        return parent[key] = v;
      });
    }
  };

  return Promise.resolve().then(function () {
    if (events.parseBefore) {
      return events.parseBefore(schema, result, parent, events);
    }
  }).then(parseMain).then(function () {
    if (events.parseAfter) {
      return events.parseAfter(schema, result, parent, events);
    }
  }).then(function () {
    return result;
  });
};

exports.parse = parse;

var conditional = function conditional(schema, conditionFunc) {
  return function (stream, result, parent, parse, events) {
    return Promise.resolve(conditionFunc(stream, result, parent, events)).then(function (ok) {
      if (ok) {
        return parse(stream, schema, result, parent, events);
      }
    });
  };
};

exports.conditional = conditional;

var loop = function loop(schema, continueFunc) {
  return function (stream, result, parent, parse, events) {
    var arr = [];

    var next = function next() {
      return Promise.resolve(continueFunc(stream, result, parent, events)).then(function (hasNext) {
        if (hasNext && !events.terminated) {
          var newParent = {};
          return parse(stream, schema, result, newParent, events).then(function () {
            return arr.push(newParent);
          }).then(next);
        } else {
          return arr;
        }
      });
    };

    return next();
  };
};

exports.loop = loop;